package org.jeecg.modules.zixishi.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.jeecg.common.api.dto.message.BusTemplateMessageDTO;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.CommonSendStatus;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SysAnnmentTypeEnum;
import org.jeecg.modules.coupon.entity.Coupon;
import org.jeecg.modules.coupon.service.ICouponService;
import org.jeecg.modules.discount.entity.Discount;
import org.jeecg.modules.discount.service.IDiscountService;
import org.jeecg.modules.goods.entity.Goods;
import org.jeecg.modules.goods.service.IGoodsService;
import org.jeecg.modules.message.websocket.WebSocket;
import org.jeecg.modules.order.entity.Order;
import org.jeecg.modules.order.service.IOrderService;
import org.jeecg.modules.zixishi.entity.*;
import org.jeecg.modules.zixishi.service.*;
import org.jeecg.modules.zixishi.vo.ZixishiPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

/**
* @Author: jeecg-boot
* @Date:   2024-05-19
* @Version: V1.0
*/
@Api(tags="小程序api")
@RestController
@RequestMapping("/zixishi/api")
@Slf4j
public class APIController {
    @Autowired
    private IQuyuService quyuService;
    @Autowired
    private ISwiperPicService swiperPicService;
    @Autowired
    private ISeatService seatService;
    @Autowired
    private IZixishiService zixishiService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private ICouponService couponService;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    private IDiscountService discountService;
    @Autowired
    private IGoodsService goodsService;
    @Value("${miniapp.force}")
    private String appForce;
    @Value("${miniapp.maxdate}")
    private Integer maxDate;

    @GetMapping("/appconfig")
    public Result<Map> appConfig(HttpServletRequest request) {
        return Result.ok(new HashMap(){{
            put("appforce",Boolean.valueOf(appForce));
            put("maxdate",maxDate);
        }});
    }
    /**
     * @return
     */
    @ApiOperation(value = "自习室列表", notes = "自习室列表")
    @GetMapping(value = "/zixishilist")
    public Result<List<ZixishiPage>> zixishiList(HttpServletRequest req) {
        List<ZixishiPage> retList = new ArrayList<>();
        List<Zixishi> zixishiList = zixishiService.list(new LambdaQueryWrapper<Zixishi>().eq(Zixishi::getStatus, 1));
        if (CollectionUtil.isNotEmpty(zixishiList)) {
            for (Zixishi zixishi : zixishiList) {
                ZixishiPage page = new ZixishiPage();
                retList.add(page);
                BeanUtils.copyProperties(zixishi, page);
                page.setSwiperPicList(swiperPicService.selectByMainId(zixishi.getId()));
            }
        }

        return Result.OK(retList);
    }

    /**
     * @return
     */
    @ApiOperation(value = "区域列表", notes = "区域列表")
    @GetMapping(value = "/quyulist")
    public Result<List<Quyu>> quyuList(@RequestParam String zixishiId, HttpServletRequest req) {
        LambdaQueryWrapper<Quyu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Quyu::getZixishiId, zixishiId);
        queryWrapper.eq(Quyu::getStatus, 1);
        return Result.ok(quyuService.list(queryWrapper));

    }

    /**
     * @return
     */
    @ApiOperation(value = "座位列表", notes = "座位列表")
    @GetMapping(value = "/seatlist")
    public Result<List<Seat>> seatList(@RequestParam String quyuId, HttpServletRequest req) {
        return Result.ok(seatService.selectByMainId(quyuId));
    }

    /**
     * @return
     */
    @ApiOperation(value = "座位占用详情", notes = "座位占用详情")
    @GetMapping(value = "/seatdetail")
    public Result<Seat> seatDetail(@RequestParam String seatId, HttpServletRequest req) {
        SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
        Seat seat = seatService.getById(seatId);

        if (StringUtils.equals("1", seat.getStatus())) {
            String day = sdfs.format(new Date());

            LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<Order>()
                    .lt(Order::getStartTime, day + " 23:59:59")
                    .gt(Order::getEndTime, new Date())
                    .in(Order::getOrderStatus, "0", "1", "2");

            List<Order> orderList = orderService.list(queryWrapper);
            if (CollectionUtil.isNotEmpty(orderList)) {
                for (Order order : orderList) {
                    Date startTime = order.getStartTime();
                    Date endTime = order.getEndTime();
                    Calendar calendar1 = Calendar.getInstance();
                    calendar1.setTime(startTime);
                    int mint1 = calendar1.get(Calendar.MINUTE);
                    mint1 = (mint1 / 30) * 30;
                    calendar1.set(Calendar.MINUTE, mint1);

                    Calendar calendar2 = Calendar.getInstance();
                    calendar2.setTime(startTime);
                    int mint2 = calendar2.get(Calendar.MINUTE);
                    mint2 = (mint2 / 30) * 30;
                    calendar2.set(Calendar.MINUTE, mint2);


                }
            }
        }
        return Result.ok();
    }

    /**
     * @return
     */
    @ApiOperation(value = "可预约座位列表", notes = "可预约座位列表")
    @GetMapping(value = "/avliseat")
    public Result<List<Seat>> avliSeat(@RequestParam String quyuId, @RequestParam String startTime, @RequestParam String endTime, HttpServletRequest req) {
        SimpleDateFormat sdfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdfd = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date st = sdfs.parse(startTime);
            Date et = sdfd.parse(endTime);
            if(st.getMinutes()%30!=0 || et.getMinutes()%30!=0){
                return Result.error("预约时间选择有误，请重新选择");
            }
        }catch (Exception ex){
            log.error(ex.getMessage());
            ex.printStackTrace();
            return Result.error(ex.getMessage());
        }
        List<Seat> seatList = seatService.selectByMainId(quyuId);
        Map<String, Seat> seatMap = seatList.stream().collect(Collectors.toMap(Seat::getId, seat -> seat));
        LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<Order>()
                .lt(Order::getStartTime, endTime)
                .gt(Order::getEndTime, startTime)
                .eq(Order::getQuyuId,quyuId)
                .in(Order::getOrderStatus, "0", "1", "2");
        List<Order> orderList = orderService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(orderList)) {
            for (Order order : orderList) {
                String seatId = order.getSeatId();
                Seat seat = seatMap.get(seatId);
                if (null != seat) {
                    seat.setStatus("2");
                }
            }
        }

        return Result.ok(seatList);
    }

    /**
     * @return
     */
    @ApiOperation(value = "根据小时差计算费用", notes = "根据小时差计算费用")
    @GetMapping(value = "/seatprice")
    public Result<Map> seatPrice(@RequestParam String quyuId, @RequestParam String reserveType, @RequestParam String startTime, @RequestParam String endTime, HttpServletRequest req) {
        try {
            Quyu quyu = quyuService.getById(quyuId);
            Zixishi zixishi = zixishiService.getById(quyu.getZixishiId());
            int status = zixishi.getStatus();
            if (1 != status) {
                return Result.error("该自习室未营业");
            }

            if (StringUtils.equals(reserveType, "datetime")) {
                Date vs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(startTime);
                Date ve = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(endTime);
                vs.setSeconds(0);
                ve.setSeconds(0);
                if(vs.getMinutes()%30 !=0 && ve.getMinutes()%30 !=0){
                    return Result.error("预约时间选择有误，请重新选择");
                }
//                ve = DateUtils.addMinutes(ve,-1);
                if (DateUtil.betweenDay(ve, vs,false)!=0) {
                    return Result.error("小时订单开始和结束日期需要在同一天");
                }
                Date s = new SimpleDateFormat("HH:mm:ss").parse(zixishi.getStarttime());
                Date e = new SimpleDateFormat("HH:mm:ss").parse(zixishi.getEndtime());
                if(e.before(s)){
                    e = DateUtils.addDays(e,1);
                }
                Date viss = new SimpleDateFormat("HH:mm:ss").parse(startTime.split(" ")[1]);
                Date vise = new SimpleDateFormat("HH:mm:ss").parse(endTime.split(" ")[1]);
                if(vise.before(viss)){
                    vise = DateUtils.addDays(vise,1);
                }
                if (viss.before(s) || vise.after(e)) {
                    return Result.error("自习室营业时间为:" + zixishi.getStarttime() + "--" + zixishi.getEndtime() + " 请重新选择时间");
                }
            }
            Map retMap = seatService.seatPrice(quyuId,reserveType,startTime,endTime);

            return Result.ok(retMap);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    /**
     * @return
     */
    @ApiOperation(value = "卡券列表", notes = "卡券列表")
    @GetMapping(value = "/couponlist")
    public Result<List<Coupon>> couponList(@RequestParam String zixishiId,@RequestParam Integer type, HttpServletRequest req) {
        try {
            MPJLambdaWrapper<Coupon> queryWrapper = new MPJLambdaWrapper<Coupon>();
            queryWrapper
                    .selectAll(Coupon.class)
                    .selectAs(Quyu::getName, Coupon::getQuyuName)
                    .leftJoin(Quyu.class,Quyu::getId, Coupon::getQuyuId)
                    .gt(Coupon::getCnt, 0)
                    .gt(Coupon::getEffectEndDate, new Date())
                    .eq(Coupon::getType,type)
                    .eq(Coupon::getStatus, 1)
                    .orderByAsc(Coupon::getIsort);
            if (StringUtils.isNotBlank(zixishiId)) {
                queryWrapper.eq(Coupon::getZixishiId, zixishiId);
            }
            List<Coupon> list = couponService.list(queryWrapper);
            return Result.ok(list);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return Result.error("请稍后重试");
    }

    /**
     * @return
     */
    @ApiOperation(value = "充值优惠列表", notes = "充值优惠列表")
    @GetMapping(value = "/discountlist")
    public Result<List<Discount>> discountList(@RequestParam String zixishiId, HttpServletRequest req) {
        try {
            List<Discount> discountList = discountService.list(new LambdaQueryWrapper<Discount>().eq(Discount::getZixishiId,zixishiId).eq(Discount::getStatus,"1"));
            return Result.ok(discountList);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return Result.error("请稍后重试");
    }

    /**
     * @return
     */
    @ApiOperation(value = "商品列表", notes = "商品列表")
    @GetMapping(value = "/goodslist")
    public Result<List<Goods>> goodsList(@RequestParam String zixishiId,@RequestParam(required = false) String goodsType, HttpServletRequest req) {
        try {
            List<Goods> goodsList = goodsService.list(new LambdaQueryWrapper<Goods>().eq(Goods::getZixishiId,zixishiId).eq(Goods::getGoodsStatus,"1").eq(StringUtils.isNotBlank(goodsType),Goods::getGoodsType,goodsType));
            return Result.ok(goodsList);
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return Result.error("请稍后重试");
    }

    @ApiOperation(value = "商品金额", notes = "商品金额")
    @PostMapping(value = "/goodsprice")
    public Result<String> goodsPrice(@RequestBody Map goodsMap, HttpServletRequest req) {
        try {
            BigDecimal amt = goodsService.goodsPrice(goodsMap);
            return Result.ok(String.format("%.2f", amt));
        } catch (Exception ex) {
            log.error(ex.getMessage(), ex);
        }
        return Result.error("请稍后重试");
    }
}
